#####################################################################
# File:         ElementContainer.py
# Product:      KnowledgeEngine
#
# Copyright:    Copyright (c) 2002, Faulkner Ltd.
# Author:       Brian Oliver
#
# Description:  This file defines the abstract ElementContainer class, the 
#               base class of all elements containers.
#
# See Also:     GenericContainer, Element
#####################################################################

#####################################################################
## Knowledge Engine Library Imports
from Common import *
from GenericContainer import GenericContainer, GenericContainerInfo
from Element import Element, ElementInfo

#####################################################################
## Zope Library Imports
# (none)

#####################################################################
## Python Library Imports
# (none)

#####################################################################
## ElementContainerInfo Class Definition
class ElementContainerInfo(GenericContainerInfo, ElementInfo):
    """
        Defines the class info methods, defining information about
        the class without needing an instance of the class
    """
    
    #---------------------------------------------------------------#
    
    def getClassName(self):
        """
            Returns the name of the class for which 
            we are providing information.
        """
        return 'ElementContainer'

    #---------------------------------------------------------------#

    def getDisplayName(self):
        """
            Return a friendly name for the class instances
            (this is used for displaying in lists etc)
        """
    
        return "Element Container"
        
    #---------------------------------------------------------------#

    def getIdentityType(self):
        """
            ABSTRACT: Return the identity type.  
            
            This is a short string used for prefixing object identities
        """
        
        return "elementcontainer"

    #---------------------------------------------------------------#

    def isInstanceOf(self, className):
        """
            Returns if the class is an instance of the specified
            className, or implements the interface specified 
            by the className
        """

        return className == 'ElementContainer' or ElementInfo.isInstanceOf(self, className) or GenericContainerInfo.isInstanceOf(self, className) 
        
    #---------------------------------------------------------------#

    def isPermittedInContainer(self, containerClassInfo, containerInstance = None, instance=None):
        """
            ABSTRACT: Returns if class instances (instance) is permitted in 
            the specified container (containerInstance)
            
            NOTE: This is from this class' instance perspective.
        """
        
        #DEFAULT RULE: ElementContainers are permitted in where Elements are permitted OR 
        #              in containers that permit them (this last disjunction allows for other special containers (like Models)
        #              to control the ElementContainers that may be children.
        return ElementInfo.isPermittedInContainer(self, containerClassInfo, containerInstance, instance) or containerClassInfo.isChildPermitted(self)

    #---------------------------------------------------------------#

    def isChildPermitted(self, childClassInfo, childInstance = None):
        """
            Returns if the specified child is permitted as a 
            child of the class' instances.
            
            NOTE: This is from this class' instance perspective.
            
            For elements containers, this always overrides what the
            return value from childClassInfo.isPermittedInContainer(...)
        """
        
        #DEFAULT RULE: ElementContainers may have Element children
        return childClassInfo.isInstanceOf('Element')
    
    #---------------------------------------------------------------#

    def onConfigureProperties(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific properties using the PropertyReflection interface.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """

        #initialise the super-class properties for reflection
        GenericContainerInfo.onConfigureProperties(self)
        ElementInfo.onConfigureProperties(self)
        
    #---------------------------------------------------------------#

#####################################################################
## ElementContainer Class Definition
class ElementContainer(GenericContainer, Element):
    """
        Base class for all Faulkner KnowledgeEngine Element Container 
        Elements
    """

    #---------------------------------------------------------------#

    #ABSTRACT TRANSIENT: a ClassInfo implementation instance to provide info about this class
    _CLASSINFO = ElementContainerInfo()

    #---------------------------------------------------------------#

    def __init__(self, id, identity):
        "Constructor for the container"        
        
        GenericContainer.__init__(self, id, identity)
        Element.__init__(self, id, identity)

    #---------------------------------------------------------------#

    def __setstate__(self, state):
        """
            Initialise the state of the Object
            (does backward compatibility)
        """

        #perform default GenericContainer persistent actions
        GenericContainer.__setstate__(self, state)
        
    #---------------------------------------------------------------#

    def onAfterInstanciation(self):
        """
            Handle Knowledge Engine specific actions after this object 
            has been loaded into memory.  
            
            This is useful for performing backwards compatibility
        """
    
        #perform Element.onAfterInstanciation processing
        Element.onAfterInstanciation(self)
        GenericContainer.onAfterInstanciation(self)
        
        ###print "DEBUG: ElementContainer.onAfterInstanciation: Completed"

    #---------------------------------------------------------------#

    def onAfterClone(self, identityMappings = {}):
        "Handle Knowledge Engine specific actions after this object has been cloned"

        GenericContainer.onAfterClone(self, identityMappings)
        Element.onAfterClone(self, identityMappings)        

        ###print "DEBUG: ElementContainer.onAfterClone: Completed"

    #---------------------------------------------------------------#

    def onAfterAdd(self):
        "Handle Knowledge Engine specific actions after this object has been added to a container"

        GenericContainer.onAfterAdd(self)
        Element.onAfterAdd(self)        

        ###print "DEBUG: ElementContainer.onAfterAdd: Completed"
        
    #---------------------------------------------------------------#

    def onBeforeDelete(self):
        "Handle Knowledge Engine specific actions before this object is deleted"

        GenericContainer.onBeforeDelete(self)
        Element.onBeforeDelete(self)        

        ###print "DEBUG: ElementContainer.onBeforeDelete: Completed"
        
    #---------------------------------------------------------------#

    def isPreviewPermitted(self):
        """
            Return if the Element is allowed to be previewed.
            
            By default all elements can't be previewed, some however
            should can be previewed. eg: HTMLHeaderFooters
        """
        
        return false
            
    #---------------------------------------------------------------#

#####################################################################
## Class Initialisation
# (none)
